<?php
/*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Dynamic Typographic Cascading Style Sheet API :
A CSS generator for typography that creates balanced, rythmic layouts and
removes the need for a reset stylesheet.

Released under the Open Cookie License. Send me a cookie if you like it.

 
Inspired by, and including work from ;
 
http://nicewebtype.com/
http://www.pearsonified.com/2011/12/golden-ratio-typography.php


 
How to use it :
	
	You can alter the baseline and add specific point sizes by altering the parameters in the GET query :
	eg. type.css.php?baseline=18&points=16,12,14

Full Options : 
	
	deploy 			- remove whitespace ready for putting on your server							eg. &deploy
	capitalise		- capitalise all headings														eg. capitalise=true
	baseline		- the vertical rythmn (grid) distance between lines in pixels					eg. baseline=22
	scale			- type scaling mode, can be linear, log, phi, pi, any number or constants		eg. scale=phi
    zoom			- resize every element by this ratio											eg. zoom=1.5
 	print			- set the CSS for printing (handy)												eg. print=true
	serif			- use serif (like newspapers), rather than san-serif fonts (like magazines)		eg. serif=true 
	mobile			- adds / overrides a scaled down mobile version for small screens				eg. mobile=embed / mobile=true 
	'any element'	- set the font size for that element 											eg. h1=36&h2=21&h3=12
	reset			- toggle between simply resetting or normalising the css
You can test this script live by including the file with get options attached such as :
  
<link rel="stylesheet" href="http://localhost/css/type.css.php?capitalise=0&print=0&p=20&baseline=22&textcol=36B6CF&linkcol=36B6CF&max=36&min=11&serif=1&underline=0">
	
 
/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// FIX : FOR PHP 4 and less we need to implement this function :(
if (!function_exists('http_build_query')) 
{
  function http_build_query($formdata, $numeric_prefix = "", $seperator="&")
  {
      $arr = array();
      foreach ($formdata as $key => $val) $arr[] = $numeric_prefix.$key."=".$val;
      return implode($arr, $seperator);
  }
}



////////////////////////////////////////////////////////////////////////
// Config : RUN ONCE!
// only create constants if we haven't meta scripted
////////////////////////////////////////////////////////////////////////
if ( !isset( $iteration )) 
{	
  
 // Super handy way of reading the current values via an include :
 // include('type.css.php?');
 
	$inputVars = array
	( 
		'h1' => 72 ,
		'h2' => 64 ,
		'h3' => 48 ,
		'h4' => 32 ,
		'h5' => 21 ,
		'h6' => 16 , 
		'blockquote' => 0,
		'blockquote p' => 22,
		'p' => 12,
		'small' => 9,
		'acronym' =>  0,
		'q' => 0 ,
		'pre' => 0 ,
		'code ' => 12 ,
		'ul,ol' => 0,
		'tt' => 0,
		'baseline' => 18,
		'textcol' => '222222',
		'linkcol' => 'ff0000',
		'max' => 96,
		'serif' => true,
		'border' => 1,
		'mobile' => 'embed'
	);					

	// store get vars in this array
	$queryString = $_SERVER['QUERY_STRING'];		// find out the Query String ?...
	$url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];			// base url (won't work for https!)
	
	$parsed_url = parse_url( $url .'?'. $queryString );	
	//var_dump($parsed_url);
	$url_query = ( !!isset($parsed_url['query'])) ? $parsed_url['query'] : "";
	parse_str($url_query, $fields);
	
	
	// transfer each query to the defaults
	foreach ($fields as $key => $val)
	{
	  $inputVars[ $key ] = $val;
	}
	//var_dump($inputVars);
/**/
	// CONSTANTS : DO NOT DISTURB!
	// just so that we can refer to the same file made with updated versions of this script	
	define( 'APP_VERSION', 0.99 );
	define( 'TITLE', "CSS BASSLines Typographic Style Sheet" );
	define( 'DESCRIPTION' , "Follows webtypography.net guidelines,\nuses a modularscale.com, \nand passes Linting at csslint.net" );
	define( 'DAYS_TO_CACHE', 28 );	// cache this css page for 2 fortnights
	define( 'PIXEL_FONT_SIZE', 16 );	// default size of font in pixels
	define( 'CSS_PRECISION', 24 );	// after the decimal point, trim to 0.000008
	
	// scale types
	define( 'PHI', 0.5 * (1 + sqrt(5)) );	//1.61803399
	define( 'PI', 3.14 );
	define( 'PERFECT_FOURTH', 4/3 );
	
	define( 'RESETABLE_STATIC_SECTIONS_HTML4', 'html, body, div, span, applet, object, iframe, fieldset, form, dfn, em, hr, font, img, ins, kbd, table, samp, tbody, tfoot, thead, tr, th, td' );

	define( 'RESETABLE_STATIC_SECTIONS_HTML5', 'article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary,time, mark, audio, video' );

	define( 'RESETABLE_STATIC_ELEMENTS', 'q, s, small, strike, strong, blockquote, pre, abbr, acronym, address, big, cite, code, del, sub, sup, tt, var, b, u, i, center, dl, dt, dd, label, legend, caption' );

	// ADD CSS HEADER ONLY *ONCE*
	header('Content-type: text/css; charset=utf-8');
	header('Expires: '.gmdate('D, d M Y H:i:s',time() + (60 * 60 * 24 * DAYS_TO_CACHE)).' GMT');	

	$iteration = 0;
}else{
	$iteration++;
};


/* ================================================================== */
// CONTROLLERS & PUBLIC FUNCTIONS =================================== */
/* ================================================================== */
if (!function_exists('getYear')):
function getYear( $copyYear = 2009 )
{
	$curYear = date('Y'); 
	return $copyYear . (($copyYear != $curYear) ? '-' . $curYear : '');
}
endif;
////////////////////////////////////////////////////////////////////////
// Special Love for certain font families and their fallbacks
// Determine which font is best suited and return it's family stack
////////////////////////////////////////////////////////////////////////
if (!function_exists('getFont')):
function getFont( $font )
{
	global $fontFamily;
	// Convert to lower case
	$font = strtolower( $font );

	// TODO : strip out whitespace from the string :
	switch ( $font ) 
	{
// Sans Serif : =============================

	    // Arial
	    case "arial": 
		  return 'Arial, "Helvetica Neue", Helvetica, sans-serif';
	    // Arial Black
	    case "arialblack": 
		  return '"Arial Black", "Arial Bold", Gadget, sans-serif';
	    // Arial Narrow
	    case "arialnarrow": 
		  return '"Arial Narrow", Arial, sans-serif';
	    // Arial Rounded
	    case "arialround":
	    case "arialrounded":
		  return '"Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif';
	    // Avant Garde
	    case "avantgarde":
		  return '"Avant Garde", Avantgarde, "Century Gothic", CenturyGothic, "AppleGothic", sans-serif';
	    // Calibri
	    case "calibri":
		  return 'Calibri, Candara, Segoe, "Segoe UI", Optima, Arial, sans-serif';
	    // Candara
	    case "candara":
		  return 'Candara, Calibri, Segoe, "Segoe UI", Optima, Arial, sans-serif';
	    // Century Gothic
	    case "centurygothic":
		  return '"Century Gothic", CenturyGothic, "AppleGothic", sans-serif';
	    // Franklin Gothic Medium
	    case "franklingothicmed":
	    case "franklingothicmedium":
		  return '"Franklin Gothic Medium", Arial, sans-serif';
	    // Frutiger
	    case "frutiger":
		  return 'Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, sans-serif';
	    // Futura
	    case "futura":
		  return 'Futura, "Trebuchet MS", Arial, sans-serif';
	    // Geneva
	    case "geneva":
		  return 'Geneva, Tahoma, Verdana, sans-serif';
	    // Gill Sans
	    case "gillsans":
		  return '"Gill Sans", "Gill Sans MT", Calibri, sans-serif';
	    // Helvetica *** DEFAULT SANS ***
	    case "helvetica":
	    case "sans":
		  return '"Helvetica Neue", Helvetica, Arial, sans-serif';
	    // Impact
	    case "impact":
		  return 'Impact, Haettenschweiler, "Franklin Gothic Bold", Charcoal, "Helvetica Inserat", "Bitstream Vera Sans Bold", "Arial Black", sans serif';
	    // Lucida Grande
	    case "lucida":
	    case "lucidagrande":
		  return '"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif';
	    // Optima
	    case "optima":
		  return 'Optima, Segoe, "Segoe UI", Candara, Calibri, Arial, sans-serif';
	    // Segoe
	    case "segoe":
		  return 'Segoe, "Segoe UI", "Helvetica Neue", Arial, sans-serif';
	    // Tahoma
	    case "tahoma":
		  return 'Tahoma, Verdana, Segoe, sans-serif';
	    // Trebuchet
	    case "trebuchet":
		  return '"Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif';
	    // Verdana
	    case "verdana":
		  return 'Verdana, Geneva, sans-serif';

// Serif Fonts =============================

	    // Adobe Caslon Pro
	    case "caslonpro":
	    case "adobecaslonpro": 
		  return '"Adobe Caslon Pro", Baskerville, Georgia, Palatino, "Times New Roman", Times, serif';
	    // Baskerville
	    case "baskerville":
		  return 'Baskerville, "Baskerville old face", "Hoefler Text", Garamond, "Times New Roman", serif';
	    // Big Caslon
	    case "caslon":
	    case "bigcaslon":
		  return '"Big Caslon", "Book Antiqua", "Palatino Linotype", Georgia, serif';
	    // Bodoni MT
	    case "bodoni":
	    case "bodonimt":
		  return '"Bodoni MT", Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif';
	    // Book Antiqua
	    case "antiqua":
	    case "bookantiqua":
		  return '"Book Antiqua", Palatino, "Palatino Linotype", "Palatino LT STD", Georgia, serif';
	    // Calisto MT
	    case "calisto":
	    case "calistomt": 
	   	  return '"Calisto MT", "Bookman Old Style", Bookman, "Goudy Old Style", Garamond, "Hoefler Text", "Bitstream Charter", Georgia, serif';
	    // Cambria
	    case "cambria":
		  return 'Cambria, Georgia, serif';
	    // Didot
	    case "didot":
	    case "sans":
		  return 'Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif';
	    // Garamond
	    case "garamond":
		  return 'Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", serif';
	    // Goudy Old Style
	    case "goudyold":
	    case "goudyoldstyle": 
	    	  return '"Goudy Old Style", Garamond, "Big Caslon", "Times New Roman", serif';
	    // Hoefler Text
	    case "hoefler":
	    case "hoeflertext": 
	    	  return '"Hoefler Text", "Baskerville old face", Garamond, "Times New Roman", serif';
	    // Lucida Bright
	    case "lucidabright": 
	    case "lucidaserif":
		  return '"Lucida Bright", Georgia, serif';
	    // Palatino
	    case "palatino":
		  return 'Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif';
	    // Perpetua
	    case "perpetua":
		  return 'Perpetua, Baskerville, "Big Caslon", "Palatino Linotype", Palatino, "URW Palladio L", "Nimbus Roman No9 L", serif';
	    // Times New Roman
	    case "times":
	    case "timesnewroman":
		  return 'TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif';

// Slab Serif =============================

	    // Rockwell
	    case "rockwell":
		  return 'Rockwell, "Courier Bold", Courier, Georgia, Times, "Times New Roman", serif';
	    // Rockwell Extra Bold
	    case "rockwellbold":
	    case "rockwellextrabold":	    
	      return 'Rockwell Extra Bold, Rockwell Bold, monospace';

// Monospaced =============================

	    // Andale Mono
	    case "andale":	   
	    case "andalemono":
		  return '"Andale Mono", AndaleMono, monospace';
	    // Consolas
	    case "consolas":
		  return 'consolas, monaco, monospace';
	    // Courier New
	    case "courier":	  
	    case "couriernew":
		  return '"Courier New", Courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace';
	    // Lucida Console
	    case "ludicamono":	    
	    case "ludicaconsole":
		  return '"Lucida Console", "Lucida Sans Typewriter", Monaco, "Bitstream Vera Sans Mono", monospace';
	    // Monaco
	    case "monaco":
		  return 'monaco, consolas, "Lucida Console", monospace';
	}

	// last resort, fall back to use our new font first...
	return "'" . $font . "'," . $fontFamily;
}
endif;


////////////////////////////////////////////////////////////////////////
// Create a single line comment
// eg. /* Comment */
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssComment')):
function cssComment( $comment, $newline=false, $carriage=false, $indentation='' )
{
	if (DEPLOY) return '';
	$css = '';
	if ($newline) $css = NEWLINE . "\r";
	$css .= $indentation . "/* " . $comment . " */";
	if ($carriage) $css .= "\r";
	return $css;
}
endif;


////////////////////////////////////////////////////////////////////////
// Create a multiple line comment
// Such as this box!
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssMultilineComment')):
function cssMultilineComment( $comment='' )
{
	if (DEPLOY) return '';
	$comments = NEWLINE . "/*/////////////////////////////////////////////////////////////////";
	$comments .= NEWLINE . $comment;
	$comments .= NEWLINE . "////////////////////////////////////////////////////////////////*/";
	return $comments;
}
endif;


////////////////////////////////////////////////////////////////////////
// Set the main generic CSS BODY Rules for type and baseline
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssBody')):
function cssBody( $font, $defaultSize )
{
	global $baseline, $textColour;
	$css = 'html{';
	// Corrects text resizing oddly in IE6/7 when body font-size is set using em units see http://clagnut.com/blog/348/#c790
	$css .= NEWLINE . TAB."font-size: 100%;";
	// Prevents iOS text size adjust after orientation change, without disabling user zoom see http://www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
	$css .= NEWLINE . TAB."-webkit-text-size-adjust:100%;";
	$css .= NEWLINE . TAB."-ms-text-size-adjust:100%;";
	// maxvoltar.com/archive/-webkit-font-smoothing
	$css .= NEWLINE . TAB."-webkit-font-smoothing:antialiased";
	$css .= NEWLINE."}";
	// Default text sizes and vertical rhythmn
	$css .= NEWLINE . 'body{';
	$css .= NEWLINE . TAB . "color:" . $textColour . ";";
	$css .= NEWLINE . TAB . "font-family: " . $font . ";";
	$css .= NEWLINE . TAB . "font-size:" . round($defaultSize*100/16) . "%;";
	$css .= NEWLINE . TAB . "line-height:" . ( round( $baseline/$defaultSize , CSS_PRECISION ) ) . ";" ;	 // This is where to set the baseline 
	// $css .= NEWLINE . TAB . "margin:0;" ;	 // This is where to set the baseline 
	// $css .= NEWLINE . TAB . "padding:0;" ;	 // This is where to set the baseline 
	// $css .= NEWLINE . TAB . "border:0;" ;	 // This is where to set the baseline 
	$css .= NEWLINE . '}';
	$css .= NEWLINE . "html>body{ font-size: " . $defaultSize . "px; }" . NEWLINE;
	return $css;
}
endif;


////////////////////////////////////////////////////////////////////////
// Create 
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssID')):
function cssID( $IDName, $fontSizeInPixels=9, $indentation='' )
{
	global $capitaliseHeadings;
	$css = NEWLINE . $indentation . $IDName . '{';
	$css .= cssRules( $fontSizeInPixels );
	if ($capitaliseHeadings && checkIsHeadline($IDName)) $css .= NEWLINE . $indentation . TAB . "text-transform:uppercase;";
	$css .= NEWLINE . $indentation . '}' . NEWLINE;
	return $css;
}
endif;


////////////////////////////////////////////////////////////////////////
// Set the desired height and receive a string in return! 
// .$className{ } 
//  eg: .font12pt{ }
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssClass')):
function cssClass( $className, $fontSizeInPixels=9, $indentation='' )
{
	$css = NEWLINE . $className . '{';
	$css .= cssRules( $fontSizeInPixels, $indentation );
	$css .= NEWLINE . '}' . NEWLINE;
	return $css;
}
endif;


////////////////////////////////////////////////////////////////////////
// Create a CSS element, class or group set and assign rules
// eg. h1{ margin:0; }
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssElement')):
function cssElement( $selector, $rules, $indentation='' )
{
	$css = NEWLINE . $indentation . $selector . '{';
	// loop through the array and create
	foreach($rules as $element => $value)
	{
		// ensure that $value ends in a ';'
		if (substr($value, -1) != ";") $value .= ";";
		// add to ruleset
		$css .= NEWLINE . $indentation . TAB . $value;
	}
	$css .= NEWLINE . $indentation . '}';
	return $css;
}
endif;


////////////////////////////////////////////////////////////////////////
// Special case for anchor element IDs
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssAnchor')):
function cssAnchor( $IDName, $color="#192d6a", $highlight="#555555", $visited="#444444", $indentation='' )
{
	global $underlineLinks;
	
	// TODO : Invert the textcolour and background colour
	//$background = ( strToLower($underlineLinks) == 'invert');
	$border = ( strToLower($underlineLinks) == 'border');
	
	// set underline
	if (!!$underlineLinks) $textDec = 'underline';
	else $textDec = 'none';
	
	// set hover style
	$hoverTextDec = $textDec;	
	
	// override for underline only on hover
	if ( strToLower($underlineLinks) == 'hover')
	{
		$hoverTextDec = 'underline';	
		$textDec = 'none';
	} 

	// override for border underline (only on hover)
	if ( $border )
	{
		$hoverTextDec = 'none';	
		$textDec = 'none';
	} 
	// a, a:link
	$css = NEWLINE . $indentation . $IDName . ",";
	$css .= NEWLINE . $indentation . $IDName . ':link{';
	$css .= NEWLINE . $indentation . TAB . "color:" . $color . ";";
	$css .= NEWLINE . $indentation . TAB . "text-decoration:" . $textDec . ";";
	if ( $border ){
		$css .= NEWLINE . $indentation . TAB . "margin-bottom:-1px;";
		$css .= NEWLINE . $indentation . TAB . "border-bottom:1px solid transparent;";
	}	
	
	$css .= NEWLINE . $indentation . '}';
	// a:hover
	$css .= NEWLINE . $indentation . $IDName . ':hover{';
	$css .= NEWLINE . $indentation . TAB . "color:" . $highlight . ";";
	$css .= NEWLINE . $indentation . TAB . "text-decoration:" . $hoverTextDec . ";";
	$css .= NEWLINE . $indentation . TAB . "outline: 0;";
	if ( $border )	$css .= NEWLINE . $indentation . TAB . "border-bottom:1px solid ".$highlight.";";
	$css .= NEWLINE . $indentation . '}';
	// a:focus
	$css .= NEWLINE . $indentation . $IDName . ':focus{';
	$css .= NEWLINE . $indentation . TAB . "color:" . $highlight . ";";
	$css .= NEWLINE . $indentation . TAB . "text-decoration:" . $textDec . ";";
	// Addresses outline displayed oddly in Chrome
	$css .= NEWLINE . $indentation . TAB . "outline: thin dotted;";
	$css .= NEWLINE . $indentation . '}';
	// a:active
	$css .= NEWLINE . $indentation . "" . $IDName . ':active{';
	$css .= NEWLINE . $indentation . TAB . "color:" . $highlight . ";";
	$css .= NEWLINE . $indentation . TAB . "text-decoration:" . $textDec . ";";
	$css .= NEWLINE . $indentation . TAB . "outline: 0;";
	$css .= NEWLINE . $indentation . '}' . NEWLINE . $indentation;
	// a:visited
	$css .= NEWLINE . $indentation . "" . $IDName . ':visited{';
	$css .= NEWLINE . $indentation . TAB . "color:" . $visited . ";";
	$css .= NEWLINE . $indentation . TAB . "text-decoration:" . $textDec . ";";
	$css .= NEWLINE . $indentation . '}' . NEWLINE;
	// return compound
	return $css;
}
endif;

////////////////////////////////////////////////////////////////////////
// Reset any number of elements to zero style
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssResetElement')):
function cssResetElement( $IDName, $marginTop=0, $marginBottom=0 )
{
	return $IDName . '{' . cssReset( $marginTop, $marginBottom ) . NEWLINE . '}' . NEWLINE;
}
endif;

////////////////////////////////////////////////////////////////////////
// Create the Typographics / Spacing Rules to populate the CSS with :
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssRules')):
function cssRules( $fontSizeInPixels=12 , $offset = 0.5, $addMargins=true )
{
	global $baseline;
	$css = '';
	// INHERIT (if fontsize is set to zero)
	// If we want this element to inherit font-size and line-weight
	if ( $fontSizeInPixels < 1 )
	{
	  $lineHeight = $baseline / PIXEL_FONT_SIZE;    // line-height: 1.125em;	= 18 / 16 px 
	  return cssMargin( 0 , $lineHeight );
	} 

	// RETYPE
	// We have a known font size, lets create the necessary rules
	if ( $fontSizeInPixels < $baseline )
	{
	  $multiplier = 1;
	  $lineHeight = $baseline / $fontSizeInPixels;    // line-height: 1.125em;	= 18 / 16 px 
	  $css .= cssMargin( 2*$lineHeight*$offset , 2*$lineHeight*(1-$offset) );  	// add margins to shorter sections
	}else{
	  // we need a bigger baseline!
	  $multiplier = ceil( $fontSizeInPixels / $baseline );			// round down
	  $lineHeight = ($multiplier*$baseline ) / $fontSizeInPixels;			// set the line height based on multiples of the baseline
	  // if the line-height is the same as the font size
	  //$css .= cssMargin( 0 , 0 );							// add fixed margins
	} 
	  
	// Apply line-height via leading
	$css .= leading( $lineHeight , $multiplier ); 				// apply Leading
	// else kern the letter spacing
	$css .= kern( $fontSizeInPixels );
	return $css;
}
endif;

////////////////////////////////////////////////////////////////////////
// Reset the style on an element and normalise their appearance
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssReset')):
function cssReset( $marginTop=0, $marginBottom=0, $resetFontSize=true )
{
	$css = "";  
	if ( $resetFontSize ) $css .= NEWLINE . TAB . "font-size:100%;";
	$css  .= cssMargin( $marginTop, $marginBottom );
	$css .= NEWLINE . TAB . "padding:0;";
	$css .= NEWLINE . TAB . "border:0;";
	$css .= NEWLINE . TAB . "outline:0;";
	$css .= NEWLINE . TAB . "vertical-align:baseline;";
	$css .= NEWLINE . TAB . "background:transparent;";
	return $css;
}
endif;

////////////////////////////////////////////////////////////////////////
// Create Top and Bottom Margins
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssMargin')):
function cssMargin( $marginTop=0, $marginBottom=0, $units='em' )
{
	$marginTop 	= round( $marginTop , CSS_PRECISION );
	$marginBottom 	= round( $marginBottom , CSS_PRECISION );

	// margin: 0;
	if (( $marginTop == 0 )&&( $marginBottom == 0 )) return NEWLINE . TAB . "margin:0;";

	$top 		= ( $marginTop == 0 ) ? 0 : $marginTop.$units;
	$bottom 	= ( $marginBottom == 0 ) ? 0 : $marginBottom.$units;

	// margin: 2px 0;
	if ( $top == $bottom ) return NEWLINE . TAB . "margin:" . $top . " 0;";

	// margin: 2px 0 4px 0;
	return NEWLINE . TAB . "margin:" . $top . " 0 " . $bottom . " 0;";
}
endif;

////////////////////////////////////////////////////////////////////////
// Create a Horizontal Rule that follows, cross-browser, to the rythmn
////////////////////////////////////////////////////////////////////////
if (!function_exists('cssHorizontalRule')):
function cssHorizontalRule( $height, $borderSize=1, $colour='#000', $print=false, $indentation='' )
{
	/*
	
	hr {
		background-color:#444;
		border-width:0;
		color:#444;
		height:2px;
		line-height:0;
		margin:-.5em 10px 1.8571em 10px;
		
		text-align:center;
		width:80%;
	}
	
	$hr = array
	(
		"color:" . $colour,    								// IE 6-8 Fix
		"border-color:" . $colour,
		"border-style:solid",
		"border-width:0 0 " . $borderSize . "px 0",
		"margin:0 0 " . ($height-$borderSize) . "px 0",
		// "padding:" . $height . "px 0 0 0",
		"height:" . $height. "px",							// IE 6 Fix
		"font-size: 1px",									// IE 6 Fix
		"line-height: 0",									// IE 6 Fix
		"text-align:center",								// IE 6 Fix   
		"clear:both",
		"page-break-after:always"							// Printing purposes : Break after HR
	);
	*/
	$hr = array
	(
		"*zoom:1",											// For IE 6/7 (trigger hasLayout)
		"clear:both",										// Give it a new horizontal position
		"display:block",									// Make sure that it is a block element
		"background-color:" . $colour,    					// FF & Webkit for line colour
		"color:" . $colour,    								// IE 6-8 Fix for line colour
		"border:0",											// Hide border 
		/*"border-top:".$borderSize."px solid transparent",		//  ISSUE : This is a test transparent
		"border:".$borderSize."px solid ". $colour,		//  ISSUE : This is a test transparent
		 "margin:" . ($height) . "px 0 " . ($height-$borderSize) . "px 0", */	 
		"margin-top:" . ($height-$borderSize) . "px",  
		"margin-bottom:". ($height-$borderSize) . "px",
		/* "padding-top:" . $height . "px",*/
		"height:" . $borderSize. "px",						/* Line size */
		"font-size:" . $borderSize. "px",					/*	IE 6 Fix */
		"line-height:0",									/* IE 6 Fix */   
		"text-align:center"									/* IE 6 Fix for centring the bar */   
	);
	
	// Printing purposes : Break after HR 
	if ($print) $hr[] = "page-break-after:always";		
	//"font-size:0","line-height:0",		"height:0"
	
	$before = array
	(
		"content:' '",
		"display:table"
	);
	
	$after = array
	(
		"clear:both",
		"content:' '",
		"display:table",
		"clear:both",
		"visibility:hidden"
	);
	/*
	.group:before,
	.group:after {
	    content: "";
	    display: table;
	} 
	.group:after {
	    clear: both;
	}
	.group {
	    zoom: 1; // For IE 6/7 (trigger hasLayout)
	}
	
	
	
	$after = array
	(
		"content:'&nbsp;'",
		"font-size:100%",
		"overflow:hidden",
		"display:table",
		"height:0",
		"width:0"
	);
	*/
	$output = cssElement( "hr,.hr", $hr, $indentation );
	$output .= cssElement( "hr:before,.hr:before", $before, $indentation );
	$output .= cssElement( "hr:after,.hr:after", $after, $indentation );
	return $output;
}
endif;

////////////////////////////////////////////////////////////////////////
// Limit the global type value sizes to between these values
////////////////////////////////////////////////////////////////////////
if (!function_exists('limitValues')):
function limitValues( $maxBaseline, $maxParagraph, $maxSize  )
{
	global $baseline, $paragraphInPoints, $maximumFontSize, $minimumFontSize, $typographyElements, $scaleRatio;
	 
	$change = true;
	//echo $baseline . ' > ' . $maxBaseline . "MOBILE VARIATIONS NEEDED? ".$change ;
  	
	if ( $baseline > $maxBaseline )
	{
		$baseline = $maxBaseline;
		$change = true;
	}
	if ( $paragraphInPoints > $maxParagraph)
	{
		$paragraphInPoints = $maxParagraph;
		$change = true;
	}
	if ( $maximumFontSize > $maxSize ) 
	{
		$maximumFontSize = $maxSize;
		$change = true;
	}
	
	// now loop through and change array!
	$typographyElements = getFontSizeRanges( $maximumFontSize, $minimumFontSize, $paragraphInPoints, $typographyElements, $scaleRatio );
	
	return $change;
};
endif;

////////////////////////////////////////////////////////////////////////
// Create all of the CSS that is dependent on size
////////////////////////////////////////////////////////////////////////
if (!function_exists('getMarkup')):
function getMarkup( $level=0 )
{
	global $fontFamily, $print, $linkActiveColour, $linkHoverColour, $linkVisitedColour, $baseline, $borderSize, $borderColour, $typographyElements;
	
	$markup = '';
	$indentation = '';
	for ( $i=0; $i< $level; ++$i ) $indentation .= TAB;
		
	// Body & Anchors
	if ($level==0) $markup .= cssBody( $fontFamily, PIXEL_FONT_SIZE );
	
	// All other elements
	foreach($typographyElements as $element => $value) $markup .= cssID( $element, $value, $indentation );
	// Ensure Links are coloured
	$markup .= cssAnchor( 'a', $linkActiveColour, $linkHoverColour, $linkVisitedColour, $indentation);
	// Horizontal Rule usually breaks vertical rythmn 
	$markup .= cssComment( "Padded Horizontal Rule" , true, true, $indentation ); 
	$markup .= cssHorizontalRule( $baseline, $borderSize, $borderColour, $print, $indentation );
	
	return $markup;
};
endif;

////////////////////////////////////////////////////////////////////////
// Create a CSS sub set that follows a group rule set such as
// eg. @media only screen and (max-device-width:480px)
// ‘aural’, ‘braille’, ‘handheld’, ‘print’, ‘projection’, ‘screen’, ‘tty’, ‘tv’
////////////////////////////////////////////////////////////////////////
if (!function_exists('mediaQuery')):
function mediaQuery( $mediaQuery, $html='' )
{
      return NEWLINE . '@media ' . $mediaQuery . NEWLINE . '{' . $html . NEWLINE . '}' . NEWLINE;
};
endif;


/* ============== TYPOGRAPHY ============================================================================ */

////////////////////////////////////////////////////////////////////////
// Leading between lines
////////////////////////////////////////////////////////////////////////
if (!function_exists('leading')):
function leading( $lineHeight , $multiplier ) 
{
	$leading = round( $lineHeight , CSS_PRECISION );
	$units = ( $leading == 0 ) ? '' : 'em';
	return NEWLINE . TAB . "line-height: ".$leading. $units ."; " . TAB . TAB . (($multiplier>1) ? cssComment($multiplier."x baselines") : '' ); 	// apply Leading	
}
endif;

////////////////////////////////////////////////////////////////////////
// Ensure that text is legible at all sizes 
// font-size: 1.33em  = 16pt / PIXEL_FONT_SIZE (12)
// Adds letter-spacing / Adds word-spacing
// All caps often benefits from a little extra letterspacing
////////////////////////////////////////////////////////////////////////
if (!function_exists('kern')):
function kern( $fontSizeInPixels=0 , $capitalise=false, $threshold = 12) 
{
	global $paragraphInPoints;
	// set font size in ems (or inherit if zero or unset)
	if ( $fontSizeInPixels > 0 ) $css = setFontSize( $fontSizeInPixels );
	// check to see if the requested size requires additional spacing
	if ( $fontSizeInPixels > $threshold )
	{
	  // font is readable at current size but may be too close to the smallest size, in which case add letter-spacing
	  if ( $fontSizeInPixels <= $paragraphInPoints ) $css .= NEWLINE . TAB . "word-spacing: 0.1em;";	// increase spacing between words
	}else{
	  // font is too small to be legible - transform
	  $css .= NEWLINE . TAB . "word-spacing: 0.2em;";	// increase spacing between words
	  $css .= NEWLINE . TAB . "letter-spacing: 1px;";	// increase gap between letters
	  // font is tiny - flip to UPPERCASE
	  if ($fontSizeInPixels < 9) $css .= NEWLINE . TAB . "text-transform:uppercase;";	
	}
	return $css;
}
endif;

////////////////////////////////////////////////////////////////////////
// A handy way to set the font-size to handle compound embedding
// The rem size works on : 
// Safari 5, Chrome, Firefox 3.6+, Internet Explorer 9, Opera 11.02
// more info : http://snook.ca/archives/html_and_css/font-size-with-rem
////////////////////////////////////////////////////////////////////////
if (!function_exists('setFontSize')):
function setFontSize( $fontSizeInPixels )
{
	$size = round( $fontSizeInPixels / PIXEL_FONT_SIZE , CSS_PRECISION );
	$css = NEWLINE . TAB . "font-size: ". $size ."em; " ;
	$css .= NEWLINE . TAB . "font-size: ". $size ."rem; "; 
	$css .= TAB . TAB . cssComment($fontSizeInPixels."pts") ; 
	return $css;
}
endif;

/* ============== PRIVATE =========================================== */

////////////////////////////////////////////////////////////////////////
// Is this element a Heading? eg H1 H2 H3...
////////////////////////////////////////////////////////////////////////
if (!function_exists('checkIsHeadline')):
function checkIsHeadline( $elementName )
{
	if ( preg_match("/h[1-9]/i", $elementName) ) return true;
	else return false;
}
endif;

////////////////////////////////////////////////////////////////////////
// If you want to create resized versions of a particular setup without
// needing to update all values. Simply set the $scale to a value that
// represents how much oversized you want the new style sheet
// eg. scale = 120 means 120% of the original setup
////////////////////////////////////////////////////////////////////////
if (!function_exists('setScale')):
function setScale( $scale )
{ 
	global $typographyElements;
	$ratio = $scale / $typographyElements['h1'];
	// loop through h1 - h6
	foreach($typographyElements as $element => $value) 
	{
	  $value = $ratio * $value;
	}
}
endif;

////////////////////////////////////////////////////////////////////////
// Get the scales for type based on the scale vector
////////////////////////////////////////////////////////////////////////
if (!function_exists('getScales')):
function getScales($maximum, $minimum, $paragraph, $scaleType)
{
	// Ensure that paragraph is larger than smallest
	if ($minimum > $paragraph) $minimum = $paragraph;
	
	// now we create an array of "modular scales"
	$harmonicScales = array();
	
	// work out the full extent of font size
	$range = $maximum - ($paragraph);
	
	// Now the fiddly part, we need to stagger the range between 7 items (including <p>)
	// the first few of which should have a larger gap between them...		
	switch ($scaleType) 
	{
		// GOLDEN RATIO
		case PHI:
			$previous = $minimum;
			for ( $i=5; $i >0; $i-- ) $harmonicScales[$i] = $maximum / (PHI * $i);
			break;
			
		case PERFECT_FOURTH:
			break;
		
		case PERFECT_FIFTH:
			break;
		
		// GOLDEN RATIO LOGARITHMNICALY	
		case 3:
			$previous = $minimum;
			for ( $i=5; $i >=0; $i-- ) $harmonicScales[$i] = $previous = ($previous * PHI);
			break;
			
		// PI nom nom nom
		case PI:
			break;
				
		// LINEAR SCALE
		default:
			$steps = round( $range / 5.5 , 0 );
			for ( $i=5; $i >=0; $i-- ) $harmonicScales[$i] = ($maximum - ($steps*$i));
			break;
	}
	
	// set up h1 as the maximum :)
	$harmonicScales[0] = 0+( $maximum );	// cast to number
			
	//var_dump($harmonicScales);
	// Overwritable elements by looping through from a-z
	$resizedTypographyElements = array
	( 
		'h1' 		=> $harmonicScales[0],
		'h2' 		=> $harmonicScales[1],
		'h3' 		=> $harmonicScales[2],
		'h4' 		=> $harmonicScales[3],
		'h5' 		=> $harmonicScales[4],
		'h6' 		=> $harmonicScales[5], 
		'p' 		=> $paragraph,
		'small' 	=> $minimum
	);
	return $resizedTypographyElements;
}
endif;

////////////////////////////////////////////////////////////////////////
// Overwrite size variables using a range of values to space apart the
// headings based on the specified scale such as PHI, PI, FOURTHS etc.
// The values returned are always within the max and min range specified.
////////////////////////////////////////////////////////////////////////
if (!function_exists('getFontSizeRanges')):
function getFontSizeRanges( $maximum, $minimum, $paragraph, $typeElements, $scaleType  )
{ 
	// Overwritable elements by looping through from a-z
	$resizedTypographyElements = getScales( $maximum, $minimum, $paragraph, $scaleType );
	
	// now plug those back into our main array :)
	foreach($resizedTypographyElements as $element => $value) 
	{
	  if ( isset($typeElements[$element]) ) $typeElements[$element] = $value;
	}

	return $typeElements;
}
endif;

////////////////////////////////////////////////////////////////////////
// Colours :D
////////////////////////////////////////////////////////////////////////
if (!function_exists('html2rgb')):
function html2rgb($colour)
{
	if ($colour[0] == '#')$colour = substr($colour, 1);

	if (strlen($colour) == 6)
	    list($r, $g, $b) = array($colour[0].$colour[1],
				    $colour[2].$colour[3],
				    $colour[4].$colour[5]);

	elseif (strlen($colour) == 3) list($r, $g, $b) = array($colour[0].$colour[0], $colour[1].$colour[1], $colour[2].$colour[2]);
	else return false;

	$r = hexdec($r); $g = hexdec($g); $b = hexdec($b);

	return array($r, $g, $b);
}
endif;

if (!function_exists('rgb2html')):
function rgb2html($r, $g=-1, $b=-1)
{
	if (is_array($r) && sizeof($r) == 3) list($r, $g, $b) = $r;

	$r = intval($r); 
	$g = intval($g);
	$b = intval($b);

	$r = dechex($r<0?0:($r>255?255:$r));
	$g = dechex($g<0?0:($g>255?255:$g));
	$b = dechex($b<0?0:($b>255?255:$b));

	$color = (strlen($r) < 2?'0':'').$r;
	$color .= (strlen($g) < 2?'0':'').$g;
	$color .= (strlen($b) < 2?'0':'').$b;
	return '#'.$color;
}
endif;

if (!function_exists('darkenHex')):
function darkenHex( $hex, $darken )
{
	$rgb = html2rgb( $hex );
	$red = $rgb[0];
	$green = $rgb[1];
	$blue = $rgb[2];
	// return as hex
	return rgb2html( $red*$darken, $green*$darken, $blue*$darken );
}
endif;

////////////////////////////////////////////////////////////////////////
// @Return a html colour from a GET query
////////////////////////////////////////////////////////////////////////
if (!function_exists('parseQueryColour')):
function parseQueryColour( $queryName='textcol' )
{
	$colour = $_GET[ $queryName ];
	return( parseColour($colour) );
}
endif;


// check to see what format the query is in... is it a hexadecimal number? (FFEEAA)
if (!function_exists( 'parseColour' )):
function parseColour( $colour )
{
	// check for a %23 or hash
	// it is a straight up number
	if (is_numeric ($colour)) return "#" . $colour;
	// probably a string starting with 00
	if (strlen($colour) == 6) return "#" . $colour;
	
	// comma delimited RGB trio (3,45,255)
	$splitRGB = explode(',', $colour);     	 // R.G.B.
	return rgb2html( $splitRGB[0], $splitRGB[1], $splitRGB[2] );
}
endif; 

/*=================================================================================*/
// MODEL :
/*=================================================================================*/

////////////////////////////////////////////////////////////////////////
// CONFIGURE SETTINGS : (You can overwrite most of these with queries)
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
// DEPLOY (Strip out whitespace) [ defaults to false ]
////////////////////////////////////////////////////////////////////////
if ( !defined( 'DEPLOY' ) ) define ( 'DEPLOY', ( isset($_GET[ 'deploy' ]) ? $_GET[ 'deploy' ] : false ) );
	
////////////////////////////////////////////////////////////////////////
// Tab / Newline switches
////////////////////////////////////////////////////////////////////////
if ( !defined( 'TAB' ) )
{
	if ( DEPLOY )
	{
		define( 'TAB', '' );
		define( 'CR', '' );
		define( 'NEWLINE', '' );
	}else {
		define( 'TAB', "\t" );
		define( 'CR', "\r" );
		define( 'NEWLINE', "\n" );
	};
}

////////////////////////////////////////////////////////////////////////
// COLOURS for the main text and links :
////////////////////////////////////////////////////////////////////////
$textColour = parseColour( $inputVars['textcol'] );

// LINKS : 
$linkActiveColour = parseColour( $inputVars['linkcol'] );

// a:hover
if ( isset($_GET[ 'hovercol' ]) ) $linkHoverColour = parseColour( $inputVars['hovercol'] );
else $linkHoverColour = darkenHex($linkActiveColour , 0.6);

// a:visited
if ( isset($_GET[ 'visitedcol' ]) ) $linkVisitedColour = parseColour( $inputVars['visitedcol'] );
else $linkVisitedColour = darkenHex($linkActiveColour , 0.9);

// underline or not (default is true)
if ( isset( $_GET[ 'underline' ])) $underlineLinks = $_GET['underline'];
else $underlineLinks = true;

// Border
if ( isset( $_GET[ 'bordercol' ])) $borderColour = parseColour( $inputVars['bordercol'] );
else $borderColour  = $textColour;

////////////////////////////////////////////////////////////////////////
// CAPITALISE Headers such as H1 H2 H3 if requested [defaults to false]
////////////////////////////////////////////////////////////////////////
if ( !isset($capitaliseHeadings) ) 
{
  if ( isset( $_GET['capitalise'] )) if ( !!($_GET['capitalise']) ) $capitaliseHeadings = true;	
  else $capitaliseHeadings = false;	
}

////////////////////////////////////////////////////////////////////////
// Sizes Set - check ensure it is a number and valid
////////////////////////////////////////////////////////////////////////
$baseline = $inputVars['baseline'];			// vertical flow spacing height between each 

// Border Size
$borderSize = $inputVars['border'];			// for HR and for adding borders to things...

////////////////////////////////////////////////////////////////////////
// Default Behaviours :
////////////////////////////////////////////////////////////////////////
// do we want to normalise or reset?
$normalise = ( ( isset($_GET[ 'reset' ]) )&&( !!($_GET['reset']) ) ) ? false : true; 

// is this for printed media or screen?
if ( !isset( $print )) $print = false; 
 
// Set font sizes if MAX and MIN set or resort to h1 if not set
$maximumFontSize = $inputVars['h1'];
if (( isset($_GET[ 'max' ]) )&&( is_numeric($_GET['max']) )) $inputVars['h1'] = $maximumFontSize = $_GET['max'];

$minimumFontSize = $inputVars['p']; 
if (( isset($_GET[ 'min' ]) ) && ( is_numeric($_GET['min']) )) $inputVars['p'] = $minimumFontSize = $_GET['min']; 

// Set paragraphInPoints size here to a sensible value = 18
$paragraphInPoints = $inputVars['p'];

// SET FONT FAMILY : Add any special fonts to our list

// Overwrite with a specific font family here
if ( !isset($customFont) && isset($_GET[ 'font' ]) ) {
	// fetch the name of the font family
	$customFont = $_GET[ 'font' ];
	$fontFamily = getFont( $customFont );
// Chooose a Font Family from either Sans or Serif set
}else if ( isset($_GET[ 'serif' ])&&!!($_GET['serif']) ) {
	$fontFamily = getFont('serif');
// No font specified, fallback to sans	
}else {
	$fontFamily = getFont('sans');
}
/*
// TODO : FONTFACE *TRUMPS* GOOGLEFONT
if ( !isset($googleFontFace) && isset($_GET[ 'googlefont' ]) )
{
	echo cssComment( "This isnt part of the reset but useful default" , true, true);
	$googleFontFace = $_GET[ 'googlefont' ];
	// first off work out which font it is from the get requested
	// family=Maven+Pro:400,500&subset=latin&v2 
	$family = "Maven+Pro";
	echo "@import url(http://fonts.googleapis.com/css?" . $googleFontFace . ")";
	$fontFamily = $family . FONTS_SANS;
}
*/
// @FONTFACE
if ( !isset($fontface) && isset($_GET[ 'fontface' ]) )
{
	$fontface = $_GET[ 'fontface' ];
	$fontFamily = $fontface;
}

// No scale set : Default Scale
$scaleRatio = PHI;
// this is the heading scale between paragraph size and max size
if ( isset($_GET[ 'scale' ] ) )
{
	// check to see firstly if it is one of our named types...
	$scaleType = strToLower( $_GET[ 'scale' ] );
	if ( $scaleType == "phi" ) $scaleRatio = PHI;
	else if ( $scaleType == "invphi" ) $scaleRatio = 1 / PHI;
	else if ( $scaleType == "fourth" ) $scaleRatio = PERFECT_FOURTH;
	else if ( $scaleType == "fifth" ) $scaleRatio = PERFECT_FIFTH;
	else if ( $scaleType == "pi" ) $scaleRatio = 3.14;
	// check to see if it as actual number!
	else if ( is_numeric($scaleType) ) $scaleRatio = $scaleType;
}

// Generate Overwritable elements (defaults)
if ( !isset( $typographyElements )) :
$typographyElements = array
( 
	'h1' => 72 ,
	'h2' => 64 ,
	'h3' => 48 ,
	'h4' => 32 ,
	'h5' => 24 ,
	'h6' => 20 , 
	'blockquote' => $paragraphInPoints+$baseline*0.5,
	'p' => $paragraphInPoints,
	'small' => 0,
	'acronym' =>  0,
	'q' => 0 ,
	'pre' => 0 ,
	'code ' => 0 ,
	'ul,ol' => 0,
	'tt' => 0
);
endif;
// Create a range of font sizes from the values retrieved from the query
if (isset( $maximumFontSize )) $typographyElements = getFontSizeRanges( $maximumFontSize, $minimumFontSize, $paragraphInPoints, $typographyElements, $scaleRatio );

// If you want to rescale everything, from small to super large as a percentage
if (( isset($_GET[ 'zoom' ]) )&&( is_numeric($_GET['zoom']) )) setScale($_GET['zoom']);

// Override any specific variable such as H1 or ABBR here
foreach($typographyElements as $element => $value) 
{
  // check to see if there is an override GET var for this value
  if (( isset($_GET[ $element ]) )&&( is_numeric($_GET[ $element]) )) $value = $_GET[ $element ];
}

/*=================================================================================*/

// SPECIAL CASE OVER-RIDES - if the user is to be printing from this page, 
// lets clean up some elements for the printer!
// == P R I N T :
if ( isset($_GET[ 'print' ])&&!!$_GET[ 'print' ] ) 
{
	$print = true;
	$textColour = '#000000';
	$linkActiveColour = '#000000';
	$linkHoverColour = '#FF0000';
	$linkVisitedColour = '#000000';
	$underlineLinks = true;
	// make sure we fit everything on one page!
	limitValues( 22, 12, 32 );
}

/*
// == M O B I L E :
// Here is where we make sure if a mobile variant requires any changes
// to be made to the settings, and if so, over-rides them
if ( isset($_GET[ 'mobile' ])&& $_GET[ 'mobile' ]==true ) 
{
	// touch screen so *always* underline links
	$underlineLinks = true;	
	limitValues( 18, 12, 36 );
}
*/

/*=================================================================================*/
// VIEW :
/*=================================================================================*/

//////////////////////////////////////////////////////////
// RESET LAYOUT ELEMENTS
//////////////////////////////////////////////////////////
if ($iteration == 0) :
	
  // Show Copyrights, License and CSS Guide
  echo cssMultilineComment
  ( 
  		TITLE . 
  		" v " . APP_VERSION . " " . ($normalise ? "Normalised":"Reset" ) .
  		"\nCreative Commons License " . getYear() . " DesignerZen" . 
  		"\n" . ((!$normalise) ? "Reset Styles" : "Normalise Styles" ) . " / Set Vertical Rythmn (".$baseline."px) / Adjust Kerning" .
  		"\n" . DESCRIPTION . "" . 
  		"\nCurrent Vertical Baseline is set at ".$baseline."px." . 
  		"\nWith a Modular Scale of " . $scaleRatio . "px " .
  		"\nMax size (H1) of " . $maximumFontSize . "px and a Min size of " . $minimumFontSize . "px"
	);

	// Resets group elements :
	echo cssComment("RESET ELEMENTS : ================================ " , true, true);
	$elementsToReset = RESETABLE_STATIC_SECTIONS_HTML4 . ', ' . NEWLINE . RESETABLE_STATIC_SECTIONS_HTML5 . ', '. NEWLINE . RESETABLE_STATIC_ELEMENTS;
	foreach($typographyElements as $element => $value) $elementsToReset .= ", " . $element;
	echo cssResetElement( $elementsToReset );
	
	// As we don't want these to be covered in our main reset loop...
	echo cssElement("button, input, select", array( "vertical-align: baseline" ) );
 
	// Set individual elements :
  		
  	// Quotations : ================================================
  	if (!$normalise)
  	{
  		// RESET :
  		echo cssElement("blockquote, q", array( "quotes:none" ) );  
  		echo cssElement("blockquote:before, blockquote:after, q:before, q:after", array( "content:''", "content:none" ) );  
  	}else{
  		// NORMALISE :
  		// hang some punctuation before and after regular quotes
  		echo cssElement("blockquote, q", array( 'quotes:"“" "”" "‘" "’"' ) );  
		// hang an oversized left quotation mark in serif style font
		echo cssElement("blockquote:before, q:before", array( 'content:"“"' ) ); // \201C\
		echo cssElement("blockquote:after, q:after", array( 'content:"”"' ) ); // \201D\
		// TODO : Nested quotes
		// markup citation listed as a parameter of the blockquote 
		echo cssElement("blockquote[cite]:after", array( "display:block", "text-align:right", 'content:"\2014\ " attr(cite)', "font-style: normal") );  
  	}

  	// prevent double padding when paragraphs are written within blockquotes
  	echo cssElement("blockquote > p", array( "padding:0","margin:0","display:inline" ));
  
  	if (!$normalise)
  	{
  		// Blank styles :
  		echo cssElement("ol,ul,nav ul,nav ol", array( "list-style:none","list-style-position:inside","list-style-image: none" ) ); 

		echo cssComment("NB : Remember to highlight inserts somehow!", true, true);
 		echo cssElement("ins", array( "text-decoration:none", "outline: thin dotted") );
		  
		echo cssComment("NB : Remember to define focus styles for accessibility!" , true, true);
  		echo cssElement(":focus", array( "outline: thin dotted" ) );
  		echo cssElement("a:hover,a:active", array( "outline: 0" ) );
  
		echo cssComment("NB : tables still need 'cellspacing='0' in the markup" , true, true); 
		echo cssElement("table", array( "border-collapse:collapse", "border-spacing:0" ) ); 
	}else{
		// Basic styles :
		echo cssElement("ol,ul", array( "list-style:none", "list-style-position:inside" ) ); 
  		// Fixes IE6/7/8 for navigation lists
	  	echo cssElement("nav ul,nav ol", array("list-style-image:none") );
	
	  	echo cssElement("ins", array( "text-decoration:none", "outline:thin dotted") );
		
		echo cssElement(":focus", array( "outline:thin dotted" ) );
 		echo cssElement("a:hover,a:active", array( "outline:0" ) );
  
  		echo cssElement("table", array( "border-collapse:collapse", "border-spacing:0" ) ); 
  		
  		// Addresses styling not present in IE7/8/9, S5, Chrome
  		echo cssComment("Addresses styling not present in IE7/8/9, S5, Chrome" , true, true); 
  		echo cssElement("abbr[title]",array( "border-bottom:1px dotted", "margin-bottom:-1px" ) ); 
	}

	// BUG FIXES : 
 	echo cssComment("FIX BUGS ===================================== " , true, true);
 	
 	// Block Display
	echo cssComment("Fixes block display not being defined in IE6/7/8/9 & FF3" , true, true);
	echo cssElement("article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section", array( "display:block" ) );
	
	// Inline-Block
	echo cssComment("Corrects inline-block display not defined in IE6/7/8/9 & FF3" , true, true);
	echo cssElement("audio, canvas, video", array( "display:inline-block", "*display:inline", "*zoom:1" ) );
	
	// Audio Controls iOS5
	echo cssComment("Prevents modern browsers from displaying 'audio' without controls & Removes excess height in iOS5 devices" , true, true);
	echo cssElement("audio:not([controls])", array("display:none","height:0"));
	
	// Corrects overflow displayed oddly in IE9
	echo cssComment("Corrects overflow displayed oddly in IE9" , true, true);
	echo cssElement("svg:not(:root)", array("overflow:hidden"));
	
	// Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
	// ISSUE: no IE6 support
	echo cssComment("Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4. IE6 Support still missing" , true, true);
	echo cssElement("[hidden]", array("display:none") );
	
	// Removes inner padding and border in FF3+ see www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
	echo cssComment("Removes inner padding and border in FF3+" , true, true);
	echo cssElement("button::-moz-focus-inner,input::-moz-focus-inner", array("border:0","padding:0") );
	
	// Re-enable default pointer on disabled stuff
	echo cssComment("Re-enable default pointer on disabled stuff" , true, true);
	echo cssElement("button[disabled],input[disabled]", array("cursor:default"));
	
	// Removes inner padding and search cancel button in S5, Chrome on OS X
	echo cssComment("Removes inner padding and search cancel button in S5, Chrome on OS X" , true, true);
	echo cssElement('input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button' , array("-webkit-appearance:none" ) );
	
endif;


//////////////////////////////////////////////////////////
// Set Body Colours & BASELINE
//////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////
// Typography : STYLE TYPED ELEMENTS
// Now loop through our array of element types to style.
//////////////////////////////////////////////////////////
echo cssComment("------=======<[ TYPOGRAPHY : BASELINE " . $baseline . " pixels ]>======-------" , true, true);
// all scaling baseline elements
echo getMarkup();

// @font-face support
if ( isset($fontface) ) echo cssElement("@font-face", array( "font-family:".$fontface , "src: url('".$fontface."')" ) );   

// Special Cases
// Prevents sub and sup affecting line-height in all browsers see gist.github.com/413930
echo cssElement("sup, sub", array( "height:0","line-height:0","position: relative","font-size: 75%" ) );
echo cssElement("sup", array( "bottom:1ex" ) );
echo cssElement("sub", array( "top: .5ex" ) );
echo cssID( "input", cssRules( 0, 0.5, false) );

//////////////////////////////////////////////////////////
// Basic Styling (delete anything here)
//////////////////////////////////////////////////////////
// remove default scrollboar in IE & improve readability across browsers
echo cssElement("textarea", array( "overflow:auto","vertical-align:top") );
// Stop monospaced text from wrapping see http://www.pathf.com/blogs/2008/05/formatting-quoted-code-in-blog-posts-css21-white-space-pre-wrap/
// Corrects font family set oddly in IE6, S4/5, Chrome see http://en.wikipedia.org/wiki/User:Davidgothberg/Test59
echo cssElement("pre,code,kbd,samp", array( "font-family:". getFont("monaco"), "_font-family:'courier new',monospace","white-space:pre","white-space:pre-wrap","word-wrap:break-word" ) );
// bold
echo cssElement("b,strong", array( "font-weight:bold" ) );
// italic
echo cssElement("q,i,em,cite,figcaption,dfn", array( "font-style:italic" ) );
// crossed out
echo cssElement("s,del,strike,del", array( "text-decoration:line-through" ) );
// TODO: highlighted
echo cssElement("mark", array( "color:".$linkVisitedColour ) );
// shrunken
//echo cssElement("small", array( "font-size:75%" ) );
// enlarged
echo cssElement("big", array( "font-variant:small-caps" ) );


// Advanced Styling
echo cssComment("------------------------------------------- >8-------------------------------------------" , true, true);

// fix html5 elements collapsing on IE
echo cssElement("article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, dialog", array( "display: block" ) );

// Cursors
echo cssComment("Custom cursors for interactivity" , true, true);
echo cssElement("abbr[title], dfn[title], acronym", array( "cursor: help" ) );
echo cssElement("label, input[type=button], input[type=submit], button", array( "cursor: pointer" ) );

// Browser over-rides
echo cssComment("Improve webkit font rendering" , true, true);
// improve webkit browsers rendering of these headlines
echo cssElement("h1,h2,h3", array( "text-rendering:optimizeLegibility" ) );

// Removes border when inside 'a' element in IE6/7/8/9, FF3
// Improves image quality when scaled in IE7 see code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
echo cssElement("img", array( "border:0","-ms-interpolation-mode: bicubic"));

//////////////////////////////////////////////////////////
// Tables : 
//////////////////////////////////////////////////////////
if ($normalise)
{
	echo cssComment("Tables (very basic layout) : " , true, true); 
	echo cssElement("table [colspan], tfoot", array( "text-align:center" ) );
	echo cssElement("table [rowspan]", array( "vertical-align:middle" ) );
	echo cssElement('[colspan="1"]', array( "text-align:left" ) );
	echo cssElement('[rowspan="1"]', array( "vertical-align:top" ) );
	echo cssElement('tr, th, td', array( "border-bottom: 1px solid ".$textColour, "margin-bottom:-1px" ) );

	// buttons ?
	echo cssElement('input, button', array( "height:".$baseline."px" ) );
}

// ============== @MEDIA QUERIES IF REQUIRED ======================

//////////////////////////////////////////////////////////
// Mobile Styles [
//////////////////////////////////////////////////////////
if ( isset($inputVars['mobile']) && ($iteration == 0) ) :

	$mobile = $inputVars['mobile'];
 // if ( $mobile ) :

//  endif;

	// if we want interactive font sizing depending on scale..
	// scale taken from BBC redeisgn Spec sheet 
	// http://www.bbc.co.uk/blogs/bbcinternet/2012/06/bbc_tv_channel_homepages_redes.html.
	if ($mobile == "embed") :
	/*
	// iPhone 4 [portrait + landscape]
	@media only screen and (resolution:326dpi)
	
	// screen and (resolution: 163dpi)
	
	// iPhone 3 [portrait + landscape]
	@media only screen and (max-device-width:480px)
	
	// iPod Touch and older [portrait + landscape] 
	@media only screen and (resolution:326dpi)
	
	// iPhone 4, Opera Mobile 11 and other high pixel ratio devices -----------
	@media
	only screen and (-webkit-min-device-pixel-ratio: 1.5),
	only screen and (-o-min-device-pixel-ratio: 3/2),
	only screen and (min-device-pixel-ratio: 1.5) 
	
	// iPads (landscape) -----------
	@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) 
	
	// iPads (portrait) -----------
	@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) 
	
	// iPad Portrait/Browser
	@media only screen and (min-width: 768px) and (max-width: 991px) {}
	
	// Mobile/Browser
	@media only screen and (max-width: 767px) {}
	
	// Mobile Landscape/Browser
	@media only screen and (min-width: 480px) and (max-width: 767px) {}
	
	// Anything smaller than standard 960
	@media only screen and (max-width: 959px) {}
	
	// iPad Portrait Only
	@media only screen and (min-width: 768px) and (max-width: 991px) and (max-device-width: 1000px) {}
	
	// Mobile Only
	@media only screen and (max-width: 767px) and (max-device-width: 1000px) {}
	
	// Mobile Landscape Only
	@media only screen and (min-width: 480px) and (max-width: 767px) and (max-device-width: 1000px) {}
	*/
    // check font sizes t see if they are too large to be read on a small screen
    $mobile = true;
	
	// add some extra stuff to the style sheet that only works on mobile devices :)
    //$mobileFixes = cssElement( "html", array("-webkit-text-size-adjust: none") );
	// j.mp/webkit-tap-highlight-color
	$mobileFixes = "";
	echo cssElement( "a:link ", array( "-webkit-tap-highlight-color") );
	
    // set some overiding underlines for links on mobiles
    if ($underlineLinks == false ) $underlineLinks = true;

    // now fetch this phpscript and include it with get options...!
    
    echo cssComment("------=======<[ MOBILE " . $baseline . " pixels ]>======-------" , true, true);
    // 1024px x 768px : Tablets / iPad (Landscape) : 
    //$mediaSelector = "only screen and (min-device-width : 768px) and (max-device-width : 1024px) )";
    // 1024 -> 991
    $mediaSelector = "only screen and (min-device-width : 991px) and (max-device-width : 1024px) )";
    $needed = limitValues( 32, 24, 96 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#f0f00; }" );

    // 991px x 768 : Tablets / iPad (Portrait)
    // Nb. Design for a width of 768px 
    //$mediaSelector = "only screen and (min-width: 768px) and (max-width: 991px)";
    // 990 -> 800
    $mediaSelector = "only screen and (min-width: 800px) and (max-width: 990px)";
    $needed = limitValues( 30, 22, 84 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#0f0f00; }" );
    
    // 959px < Anything smaller than standard 960px 
    //$mediaSelector = "only screen and (max-width: 959px)";
    // 768 -> 799
    $mediaSelector = "only screen and (min-width: 768px) and (max-width: 800px) and (max-height:768px)";
    $needed = limitValues( 24, 16, 72 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#0ff000; }" );
	
    // 768px -> 480px : Mobile (Landscape) : Nb. Design for a width of 480px
   	$mediaSelector = "only screen and (min-width: 480px) and (max-width: 768px) and (max-height:480px)";
    $needed = limitValues( 22, 14, 54 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#000ff0; }" ); 

    // < 767px : Mobiles : (Portrait) : Nb. Design for a width of 320px 
    //$mediaSelector = "only screen and (max-width: 767px)";
    //$needed = limitValues( 20, 14, 48 );
    //if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#00ff00; }" );
	
	// 300px -> 800px : Mobiles (Portrait) : Nb. Design for a width of 320px 
    //$mediaSelector = "all and (max-width: 800px) and (min-width: 300px)";
    // 480 -> 300
    $mediaSelector = "only screen and (max-width: 480px) and (max-height:320px)";
    $needed = limitValues( 18, 14, 24 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes . "\n body{ background-color:#ff0; }" );
		
	// < 479px : Mobile Portrait Size to Mobile Landscape Size (devices and browsers)
	//$mediaSelector = "only screen and (max-width: 479px)";
    //$needed = limitValues( 16, 12, 18 );
    //if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes. "\n body{ background-color:#ff00ff; }" );

	// < 320px : Tiny size!
	$mediaSelector = "only screen and (max-width: 320px) and (max-height:320px)";
    $needed = limitValues( 14, 10, 16 );
    if ($needed) echo mediaQuery( $mediaSelector, getMarkup( 1 ) . $mobileFixes );

  endif;

  //////////////////////////////////////////////////////////
  // If we want this whole script to be mobile specific...
  //////////////////////////////////////////////////////////
  if ( !!$_GET[ 'mobile' ] ) :

  endif;

  
// ] END Mobile Fixes :P
endif;


//////////////////////////////////////////////////////////
// BEGIN EMBEDDED @PRINT MODE :
// Inlined to avoid required HTTP connection: h5bp.com/r
//////////////////////////////////////////////////////////
if ( isset($_GET[ 'print' ])&&$_GET[ 'print' ]=="embed" ) :

  // Over-write some variables 
  $textColour = '#000000';
  $linkActiveColour = '#000000';
  $linkHoverColour = '#FF0000';
  $linkVisitedColour = '#000000';
  $underlineLinks = true;
  
  // reduce the size of the text to absolute sizes
  limitValues( 22, 12, 32 );

  // Create elements and add
  $printHTML = cssComment("Special Print CSS" , true, true); 

  // Body & Anchors (if not embedded)
  if (!$print)
  {
    $printHTML .= cssBody( $fontFamily );
    $printHTML .= cssAnchor( 'a', $linkActiveColour, $linkHoverColour, $linkVisitedColour );
    $printHTML .= cssHorizontalRule( $baseline, $borderSize, $textColour, true );
  }
  // All other elements
  foreach($typographyElements as $element => $value) $printHTML .= cssID( $element, $value );

  // External Links :
  $printHTML .= cssElement("a:link:after, a:visited:after, a:link::after, a:visited::after", array( 'content:" (" attr(href) ")"' , 'font-size: 90%' ) );
  // Internal Links :
  $printHTML .= cssElement('a[href^="/"]:after', array( 'content:" (http://' . $_SERVER['HTTP_HOST'] . '" attr(href) ")"' ) );
  // Do not show javascript and internal links
  $printHTML .= cssElement('a[href^="javascript:"]:after, a[href^="#"]:after', array('content: ""') );
  // Show abbreviations unabbreviated
  $printHTML .= cssElement('abbr[title]:after', array('content: " (" attr(title) ")"') );


  // Page Breaks
  //$printHTML .= cssElement('hr', array('page-break-after:always' ) );
  // Prevent subheadings from ending pages
  $printHTML .= cssElement('h2,h3', array("page-break-after:avoid" ) );
  // Ensure that these elements do not cross a page break
  $printHTML .= cssElement('pre,blockquote,tr,img', array("page-break-page-break-inside:avoid" ) );

	// Remove backgrounds, shadows and set all text to BLACK (as black prints faster: h5bp.com/s )
	$printHTML .= cssElement("*", array("background:transparent !important","color:" . $textColour . " !important", "text-shadow: none !important", "filter:none !important","-ms-filter: none !important" ) );
	
	// Not sure!
	$printHTML .= cssElement("p,h2,h3", array("orphans:3","widows:3" ) );
	
	// A conditional just for printed pages...
	// @page { margin: 0.5cm; }
	
	// Check to see if the user wants this as a seperate thing
	// Wrap it all up in a media query :D
	if ($print) echo mediaQuery( "print", $printHTML );
	else echo $printHTML;
	
endif;
// < END PRINTING

//////////////////////////////////////////////////////////
// Utilities for text & list styling
//////////////////////////////////////////////////////////
echo cssComment("------=======<[ HTML UTILS ]>======-------" , true, true);
echo cssElement( ".text-left", array( "text-align:left" ));
echo cssElement( ".text-right", array( "text-align:right" ));
echo cssElement( ".text-center,.text-centre", array( "text-align:center" ));
echo cssElement( ".required", array( "color:red" ));

// Assistive text : Text meant only for screen readers
echo cssElement( ".assistive-text,.screen-reader-text", array( "position:absolute !important","clip:rect(1px,1px,1px,1px)" ));

// Wrap long lines in sentences
echo cssElement( ".wrap-long-lines", array( /* CSS 2.0 */"white-space:pre",/* CSS 2.1 */"white-space:pre-wrap",/* CSS 3.0 */"white-space:pre-line",/* Opera 4-6 */"white-space:-pre-wrap",/* Opera 7 */"white-space:-o-pre-wrap",/* Mozilla */"white-space:-moz-pre-wrap",/* HP Printers */"white-space:-hp-pre-wrap", /* IE 5+ */"word-wrap:break-word" ));

// Style Lists Options
echo cssElement( "ul.square", array( "list-style:square outside" ));
echo cssElement( "ul.circle", array( "list-style:circle outside" ));
echo cssElement( "ul.disc", array( "list-style:disc outside" ));
echo cssElement( "ul.none", array( "list-style:none" ));

echo cssElement( "ol.numbered", array( "list-style:decimal" ));
echo cssElement( "ol.alphabetic", array( "list-style:lower-alpha" ));

?>